package chances.wechat.gateway;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import chances.framework.ufs.UserDirectory;
import chances.framework.ufs.UserFile;
import chances.framework.ufs.UserFileSystem;
import chances.utils.ImageUtils;
import chances.wechat.WechatConstant;
import chances.wechat.api.OauthAPI;
import chances.wechat.controller.UserAbstractController;
import chances.wechat.entity.UserMedia;
import chances.wechat.entity.WechatUser;
import chances.wechat.resp.ResultResponse;
import chances.wechat.service.UserMediaService;
import chances.wechat.service.WechatUserService;
import fastweixin.api.response.DownloadMediaResponse;
import net.coobird.thumbnailator.Thumbnails;

/*@RestController*/
public class WechatController extends UserAbstractController {

	@Autowired
	UserFileSystem userFileSystem;

	@Autowired
	WechatUserService userService;

//	@Autowired
//	TokenFactory tokenFactory;

	@Autowired
	UserMediaService userMediaService;

	Logger logger = LoggerFactory.getLogger(WechatController.class);

	public static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize";

	public static final String responseType = "code";

	@RequestMapping("/oauth2_url")
	public ResultResponse<String> getOauth2Url(@RequestParam("redirect_uri") String redirectUri,
			@RequestParam("state") String state, @RequestParam("scope") String scope,
			@RequestParam("app_code") String appCode) throws IOException {
//		ResultResponse<String> result = new ResultResponse<>();
//		result.setCode(SUCCESS);
//		try {
//			state = URLEncoder.encode(state, "utf-8");
//		} catch (UnsupportedEncodingException e) {
//			e.printStackTrace();
//		}
//		StringBuffer sb = new StringBuffer(OAUTH_URL);
//		TokenSet tokenSet = tokenFactory.getTokenSet(appCode);
//		sb.append("?appid=").append(tokenSet.getAppId()).append("&redirect_uri=").append(redirectUri)
//				.append("&response_type=").append(responseType).append("&scope=").append(scope).append("&state=")
//				.append(state).append("#wechat_redirect");
//		result.setResult(sb.toString());
//		return result;
	    return null;
	}

	@RequestMapping("/jsapi_ticket")
	public ResultResponse<String> getJsapiTicket(@RequestParam("app_code") String appCode) throws IOException {
//		String jsapi_ticket = "";
//		ResultResponse<String> result = new ResultResponse<>();
//		result.setCode(SUCCESS);
//		try {
//			jsapi_ticket = tokenFactory.getJsApiTicket(appCode);
//			result.setResult(jsapi_ticket);
//		} catch (Exception e) {
//			result.setCode(SYS_ERROR);
//		}
//		return result;
	    return null;
	}

	@RequestMapping("/download")
	public ResultResponse<String> download(@RequestParam("app_code") String appCode,
			@RequestParam("media_id") String mediaId, @RequestParam("user_id") String openId) throws IOException {

//		String accessToken = tokenFactory.getAccessToken(appCode);
//		WechatUser wechatUser = userService.getWechatUser(openId);
//		logger.info("download image userId:{},mediaId:{},token:{}", openId, mediaId, accessToken);
//		MediaAPI mediaAPI = new MediaAPI(accessToken);
//		ResultResponse<String> res = new ResultResponse<String>();
//		DownloadMediaResponse downloadMediaResponse = mediaAPI.downloadMedia(mediaId);
//
//		res.setCode(SUCCESS);
//		if (StringUtils.isNotEmpty(downloadMediaResponse.getErrcode())) {
//			res.setCode(SYS_ERROR);
//		} else {
//			String fileName = "/photo/" + mediaId + ".jpg";
//			UserFile userFile = saveFile(downloadMediaResponse, openId, fileName);
//			if (userFile.exists()) {
//				UserMedia result = createUserMedia(wechatUser, fileName, userFile, mediaId);
//				convert(result, userFile);
//			} else {
//				res.setCode(SYS_ERROR);
//			}
//
//		}
//		return res;
	    return null;
	}

	private UserMedia createUserMedia(WechatUser wechatUser, String fileName, UserFile userFile, String mediaId)
			throws IOException {
		UserMedia result = new UserMedia();
		result.setOpenId(wechatUser.getOpenId());
		result.setMediaId(mediaId);
		Dimension dim = ImageUtils.getDimension(userFile.getFile());
		result.setHeight(dim.height);
		result.setWidth(dim.width);
		result.setType("photo");
		result.setSource(fileName);
		result.setStatus(UserMedia.PHOTO_NO_AUDIT);
		result.setNickname(wechatUser.getNickname());
		this.userMediaService.insertMedia(result);
		logger.info("save media :{}", fileName);
		return result;
	}

	private UserFile saveFile(DownloadMediaResponse downloadMediaResponse, String openId, String fileName)
			throws IOException {
		UserDirectory userdirectory = userFileSystem.getUserDirectory(openId);
		UserFile userFile = userdirectory.getUserFile(fileName);
		logger.info("save file :{}", userFile.getFile().getAbsolutePath());
		UserFile uf = userdirectory.createUserFile("photo");
		if (!uf.getFile().exists()) {
			uf.getFile().mkdirs();
		}
		OutputStream out = null;
		try {
			out = userFile.getOutputStream();
			downloadMediaResponse.writeTo(out);
			out.flush();
		} finally {
			IOUtils.closeQuietly(out);
		}
		return userFile;
	}

	@SuppressWarnings("unused")
	public void convert(final UserMedia media, UserFile userFile) throws MalformedURLException, IOException {
		int width = media.getWidth();
		int height = media.getHeight();
		if (width <= 0 || height <= 0) {
			return;
		}
		String msgId = "" + media.getMediaId();
		File aFile = new File(userFile.getAbsolutePath());
		File parent = aFile.getParentFile();
		File icon = new File(parent, "icon_" + msgId + ".jpg");
		File hd = new File(parent, "hd_" + msgId + ".jpg");
		File sd = new File(parent, "sd_" + msgId + ".jpg");
		try {
			int iconSize = 250;
			if (width < height) {
				Thumbnails.of(aFile).sourceRegion(0, (int) (height - width) / 2, width, width).size(iconSize, iconSize)
						.outputFormat("jpg").toFile(icon);
			} else {
				Thumbnails.of(aFile).sourceRegion((int) (width - height) / 2, 0, height, height)
						.size(iconSize, iconSize).outputFormat("jpg").toFile(icon);
			}
			Thumbnails.of(aFile).size(1280, 720).outputFormat("jpg").toFile(hd);

		} catch (Exception e) {
		}
		logger.info("convert media :{}", userFile.getFile().getAbsolutePath());
	}

	@RequestMapping("/user_info")
	public ResultResponse<WechatUser> getUserInfo(@RequestParam("user_id") String openId,
			@RequestParam("type") String type, @RequestParam("code") String code,
			@RequestParam("app_code") String appCode) throws IOException {
//		ResultResponse<WechatUser> res = new ResultResponse<WechatUser>();
//		res.setCode(SUCCESS);
//		TokenSet tokenSet = tokenFactory.getTokenSet(appCode);
//		OauthAPI oauthAPI = new OauthAPI(tokenSet.getAppId(), tokenSet.getSecret());
//		String accessToken = tokenSet.getAccessToken();
//		Map<String, Object> snsToken = oauthAPI.getSnsToken(accessToken);
//		String token = (String) snsToken.get("access_token");
//		saveWechatUser(openId, type, res, oauthAPI, accessToken, token);
//		return res;
	    return null;
	}

	private void saveWechatUser(String openId, String type, ResultResponse<WechatUser> res, OauthAPI oauthAPI,
			String accessToken, String token) {
		WechatUser wechatUser = this.userService.getWechatUser(openId);
		if (wechatUser == null) {
			Map<String, Object> userInfo = null;
			if (WechatConstant.LOGIN_BASE.equals(type)) {
				userInfo = oauthAPI.getUserInfo(accessToken, openId);
			} else {
				userInfo = oauthAPI.getSnsUserInfo(token, openId);
			}
			Object errorCode = userInfo.get("errcode");
			if (errorCode == null) {
				wechatUser = this.toWechatUser(userInfo);
				res.setResult(wechatUser);
				this.userService.insertWeixinUser(wechatUser);
			} else {
				res.setCode(SYS_ERROR);
			}
		} else {
			this.userService.updateWeixinUserLoginTime(openId);
			res.setResult(wechatUser);
		}
	}

	private WechatUser toWechatUser(Map<String, Object> userInfo) {
		WechatUser wechatUser = new WechatUser();
		wechatUser.setSex(Integer.parseInt(userInfo.get("sex") + ""));
		Date subTime = new Date();
		String subscribetime = userInfo.get("subscribetime") + "";
		if (StringUtils.isNotEmpty(subscribetime) && !subscribetime.equals("null")) {
			subTime.setTime(Long.parseLong(subscribetime));
		}
		wechatUser.setSubTime(subTime);
		wechatUser.setStatus(WechatUser.ENABLE_STATUS);
		wechatUser.setUnionId(userInfo.get("unionid") + "");
		String city = userInfo.get("city") + "," + userInfo.get("province") + "," + userInfo.get("country");
		wechatUser.setCity(city);
		wechatUser.setLang(userInfo.get("language") + "");
		wechatUser.setOpenId(userInfo.get("openid") + "");
		wechatUser.setAvator(userInfo.get("headimgurl") + "");
		String nickname = userInfo.get("nickname") + "";
		try {
			nickname = URLEncoder.encode(nickname, "UTF-8");
		} catch (UnsupportedEncodingException e) {

		}
		wechatUser.setNickname(nickname);
		return wechatUser;
	}
	
	/*@RequestMapping("/snslogin")
	public WechatToken sns(@RequestParam("code") String code,
			@RequestParam("type")  String type,
			@RequestParam("state")  String state,
			@RequestParam("app_code") String appCode) {
		
		UserResultResponse<WechatUser> res = new UserResultResponse<WechatUser>();
		res.setCode(SUCCESS);
		TokenSet tokenSet = tokenFactory.getTokenSet(appCode);

		OauthAPI oauthAPI = new OauthAPI(tokenSet.getAppId(), tokenSet.getSecret());
		String atoken = tokenFactory.getAccessToken(appCode);
		oauthAPI.setAccessToken(atoken);
		Map<String, Object> accessTokenResponse = oauthAPI.getSnsToken(code);
		String token = (String) accessTokenResponse.get("access_token");
		String openId = (String) accessTokenResponse.get("openid");
		WechatToken weixinToken = new WechatToken(token, openId);
		saveWechatUser(openId, type, res, oauthAPI, tokenSet.getAccessToken(), token);
		if ("code".equals(type)) {
			super.deviceBind(openId, state);
		}
		return weixinToken;
	}*/

}
